package client.gui;
import sharedspace.CalendarComboBox;
import sharedspace.Course;
import sharedspace.DateUtils;
import sharedspace.ExecuteTest;
import sharedspace.Executetestinfo;
import sharedspace.ManualTest;
import sharedspace.MyFile;
import sharedspace.QuestionInTest;

import sharedspace.Teacher;
import sharedspace.Test;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.io.File;

import java.io.IOException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import javax.swing.*;
import javax.swing.table.TableColumn;


import client.GetFileFromServer;

import sharedspace.FileHandler;

import messages.MessageAllExams;
import messages.MessageAllocateExecuteTesT;
import messages.MessageAllocateExecuteTesTInfo;
import messages.MessageCoursesOfTeacher;
import messages.MessageExamOfCourse;
import messages.MessageExcuteExamByCourseID;
import messages.MessageGetManualByTestID;
import messages.MessageGetWordFile;
import messages.MessageQuestionListByTestID;
import messages.MessageStudentInCourse;
import messages.MessageTeacherSubject;


import sharedspace.User;
/**
 * This JPanel is a panel for Teacher to execute exam by choosing the test, fill the time and date.
 * @author Amir S.
 * @author Jacob C.
 * @author Maya G.
 * @author Michael V.
 *
 */
public class GUI_Teacher_Execute_Exam extends JPanel {

	public JButton btnBack = null;
	public User user;
	public ExecuteTest executeTest;
	public Client_GUI MS;
	private JComboBox<String> cmbCourses;
	public final Calendar  current = new GregorianCalendar();
	private CalendarComboBox popupCal;
	private ArrayList<Course> cList; 
	private JTable examJTable=null;
	private JPanel panelTest;
	private String subjectId;
	private JScrollPane scrollPane=null;
	private JButton btnView;
	private File fileTeacher;
	private ArrayList <Test> tList;
	private JTextField txtInsertCode;
	private JTextField txtHh;
	private JTextField txtMm;
	private String courseChoosen;
	public  byte[] teacherFileByteArray;
	private ArrayList<Test> tdList;
	private Calendar c;

	
	public GUI_Teacher_Execute_Exam(Client_GUI ms,User user) {
		super();
		this.user = user;
		this.MS=ms;
		this.initialize();
	}// end constructor

	public void initialize() {
		executeTest = new ExecuteTest();
		Date d = new Date();
		c = Calendar.getInstance();
		c.setTime(d);
		int year = c.get(Calendar.YEAR);
		cmbCourses = new JComboBox<String>();
		cmbCourses.setBounds(320, 145, 219, 20);
		getTeacherCourses(year);
		
		
		btnBack = new JButton();	
		btnBack.setText("Back");
		btnBack.setFont(new Font("Arial", Font.PLAIN, 16));
		btnBack.setBounds(new Rectangle(76, 612, 107, 30));
		btnBack.setVisible(true);
		
		GUI_ImagePanel background =new GUI_ImagePanel(new ImageIcon("images/background1.jpg").getImage());
		background.setLocation(0, 0);
		background.setSize(new Dimension(1000, 700));
		this.add(btnBack);
		this.setSize(1000, 700);
		this.setLayout(null);
		this.add(background);
		
		
		background.add(cmbCourses);
		
		
		cmbCourses.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				if(cmbCourses.getSelectedIndex() > 0){   //if a subject was selected 
					{
					  courseChoosen = (String)cmbCourses.getSelectedItem(); // get the subject that was selected
						for(int i=0; i<cList.size();i++){ 					// find the subject in arrayList recieve from message
							if(courseChoosen==cList.get(i).getCourseName()){
								subjectId=cList.get(i).getSubjectID();
								courseChoosen=cList.get(i).getCourseID();
							}
						}//end for
							}

					
					cmbCourses.setEnabled(true);
					getExamtoDisplay();
					
				}//end if
			}});

	

		
		panelTest = new JPanel();
		panelTest.setBounds(217, 200, 600, 132);
		background.add(panelTest);
		panelTest.setBorder(null);
		panelTest.setLayout(new BorderLayout(0, 0));
		
		JLabel title = new JLabel();
		title.setBounds(53, 32, 197, 59);
		background.add(title);
		title.setFont(new Font("Arial", Font.BOLD | Font.ITALIC, 28));
		title.setForeground(Color.BLUE);
		title.setText("Excute Test");
		
		JLabel lblDueDate = new JLabel("Test Date:");
		lblDueDate.setFont(new Font("Tahoma", Font.BOLD, 16));
		lblDueDate.setBounds(388, 495, 89, 14);
		background.add(lblDueDate);
		lblDueDate.setHorizontalAlignment(SwingConstants.RIGHT);
		
		popupCal = new CalendarComboBox();
		popupCal.setBounds(486, 485, 159, 30);
		background.add(popupCal);
		btnView = new JButton();	
		btnView.setBounds(635, 350, 127, 30);
		background.add(btnView);
		btnView.setText("Show Test");
		btnView.setFont(new Font("Arial", Font.PLAIN, 16));
		btnView.setVisible(true);
		btnView.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				String str=new String();
				if (examJTable.getSelectedRow()!=-1){
					 str="manual test";
				if (str.equalsIgnoreCase(tdList.get((examJTable.getSelectedRow())).getCommentForStudent())==true)
					showManualTest();

				else ViewExamSelect(examJTable.getSelectedRow());
				}else showMessage("No Test was Selected", "Show Test", JOptionPane.WARNING_MESSAGE);
			}
		});
		
		JButton btnExecute = new JButton();	
		btnExecute.setBounds(233, 613, 127, 30);
		background.add(btnExecute);
		btnExecute.setText("Execute Test");
		btnExecute.setFont(new Font("Arial", Font.PLAIN, 16));
		btnExecute.setVisible(true);
		btnExecute.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
			
					checkTheInput();
			}
		});
		
		

		
		txtInsertCode = new JTextField();
		txtInsertCode.setText("insert code");
		txtInsertCode.setBounds(292, 492, 86, 20);
		background.add(txtInsertCode);
		txtInsertCode.setColumns(10);
		
		JLabel lblCode = new JLabel("Code:");
		lblCode.setFont(new Font("Tahoma", Font.BOLD, 16));
		lblCode.setBounds(217, 495, 54, 14);
		background.add(lblCode);
		
		JLabel lblSelectCourseOf = new JLabel("Select Course of Test:");
		lblSelectCourseOf.setFont(new Font("Tahoma", Font.PLAIN, 18));
		lblSelectCourseOf.setBounds(350, 120, 180, 20);
		background.add(lblSelectCourseOf);
		
		txtHh = new JTextField();
		txtHh.setFont(new Font("Arial", Font.PLAIN, 16));
		txtHh.setText("Hh");
		txtHh.setBounds(760, 491, 31, 23);
		background.add(txtHh);
		txtHh.setColumns(10);
		
		JLabel label = new JLabel(":");
		label.setFont(new Font("Arial", Font.BOLD, 16));
		label.setBounds(803, 490, 16, 24);
		background.add(label);
		
		JLabel lblInsetTime = new JLabel("Inset Time:");
		lblInsetTime.setFont(new Font("Tahoma", Font.BOLD, 16));
		lblInsetTime.setBounds(655, 491, 95, 20);
		background.add(lblInsetTime);
		
		txtMm = new JTextField();
		txtMm.setFont(new Font("Arial", Font.PLAIN, 16));
		txtMm.setText("Mm");
		txtMm.setBounds(829, 491, 37, 23);
		background.add(txtMm);
		txtMm.setColumns(10);
		
		  
		
	}//end initialize()
	
	
	/**
	 * checks the input before execution a test is executed
	 */
	public void checkTheInput(){
		
		// the user didn't select a course from the list
		if(cmbCourses.getSelectedIndex()==0){
			showMessage("Please Choose Course", "Input Check", JOptionPane.WARNING_MESSAGE);
			return;
		}
		//  insert code
		else if( checkCodeInput(txtInsertCode.getText())!=true){
		showMessage("Error,please insert code in 4 characters (leters and numbers only)", "Wrong Code", JOptionPane.WARNING_MESSAGE);
			return;
		}
		// Date was not selected 
		
		else if((popupCal.getDate().getTime().compareTo(c.getTime()))<0 ){
			
			showMessage("Please select valid date to execute the test", "Input Check", JOptionPane.WARNING_MESSAGE);
			return;
		}// Valid hour was not selected 
		else if(hourCheck()!=true){
			showMessage("Please Inset valid Hour", "Hour field", JOptionPane.WARNING_MESSAGE);
			return;
		}// no button was chosen 
		else if(minuteCheck()!=true){
			showMessage("Please Inset valid Minutes in test", "Minutes field", JOptionPane.WARNING_MESSAGE);
			return;

		}// computerized test
		else if(examJTable.getSelectedRow()==-1){
			showMessage("Error, you did'nt choose any test from Table", "", JOptionPane.WARNING_MESSAGE);
			return;
		}
		

		//set all the execute test fields
		Teacher teacher = new Teacher(user);
		
		executeTest.setExecuter(teacher);
		executeTest.setTest(tdList.get((examJTable.getSelectedRow())));
		executeTest.setExecuteTestID("00");// real number will be allocated in sql 
		executeTest.setSubjectID(subjectId);
		//executeTest.setTestCode(txtInsertCode.getText());
		executeTest.setTestSemster(DateUtils. currentSemester());
		executeTest.setTestStatus(true);
		executeTest.setTestYear(DateUtils. currentYear());
		
		
			String str=new String();
			str="manual test";
		if (str.equalsIgnoreCase(tdList.get((examJTable.getSelectedRow())).getCommentForStudent())==true){ //if its a manual test

			executeTest.setTestType("manual");
			str=findTestPath(tdList.get((examJTable.getSelectedRow())).getTestID());

			executeTest.setWordTestPath(str);						//find the rigth path of file
			
		}else executeTest.setTestType("computerized");
		
		//set all the executeinfo fields
		String exeID=SaveExecuteTest(executeTest);
		Executetestinfo executeInfo=new Executetestinfo();
		executeInfo.setExecuteTestID(exeID); 
		executeInfo.setExtraTime(0);
		executeInfo.setNumberStudentFinish(0);
		executeInfo.setNumberStudentStart(0);
		executeInfo.setStartTime(setDateTime());
		executeInfo.getExecuteTestID();
		SaveExecuteTestInfo(executeInfo);
		
		JOptionPane.showMessageDialog(null,"Your test was saved ");
		MS.setContentPane(MS.tchr);
		
	}// end checkTheInput

	
	/**
	 * find the path of file from execute test list
	 * @param testID
	 */
	public String findTestPath(String testID) {
		
		MessageGetManualByTestID MbtI = new MessageGetManualByTestID (testID);
		try{
			MS.client.sendToServer(MbtI);// get list of teacher subject
			
			ManualTest manualTest = (ManualTest)MS.client.GetMessage();
			
			 return manualTest.getPath();
			
	} catch (IOException e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	}
		return null;
	}//end findTestPath
	
	/**
	 * Direction to saves the Executed  test in DB 
	 * @param ExecuteTest
	 */
	public String SaveExecuteTest(ExecuteTest executeTest)
	{
		String ExecuteID=new String() ;
		int sCount=0;
		MessageAllocateExecuteTesT  Msgs = new MessageAllocateExecuteTesT(executeTest);
		try{
			MS.client.sendToServer(Msgs);
			ExecuteID=(String)MS.client.GetMessage();
		} catch (IOException e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	}
	
		return ExecuteID;
	}// SaveExecuteTest
	
	/**
	 * Direction to saves the Executedinfo  test in DB 
	 *  @param ExecuteTest
	 */
	public String SaveExecuteTestInfo(Executetestinfo executeTestInfo)
	{
		String ExecuteInfoID=new String() ;
		MessageAllocateExecuteTesTInfo  Msgsi = new MessageAllocateExecuteTesTInfo(executeTestInfo);
		try{
			MS.client.sendToServer(Msgsi);
			ExecuteInfoID=(String)MS.client.GetMessage();
		} catch (IOException e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	}
	
		return ExecuteInfoID;
	}// getExecuteTestID*/
	
	/**
	 * Check if the selected teacher file is a valid.
	 * for the type of:  {doc, docx, pdf, xls, xlsx, txt}
	 * @return true if contain as extension only one of the above extensions
	 */
	public boolean isValidFileExtension(){
		return FileHandler.isValidFileExtension(fileTeacher);
	}// end function isValidFileExtension
	/**
	 * convert Date chosen into Timestamp
	 * @return Timestamp
	 */
	public Timestamp  setDateTime(){
		Date date=popupCal.getDate().getTime();
		Timestamp t = new Timestamp(date.getTime());
		String convert =t.toString();
		String ymd=convert.substring(0, 10);
		String Hh=txtHh.getText();
		if(Integer.parseInt(Hh)<10){
			if (Hh.substring(0)=="0"){
			Hh="0"+Hh;}}
		String Mm=txtMm.getText();
		if(Integer.parseInt(Mm)<10){
			if (Mm.substring(0)=="0"){
			Mm="0"+Mm;}}
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	        String in = ymd+" "+Hh+":"+Mm+":"+"00";
	        try {
	            Date theDate = dateFormat.parse(in); 
	            System.out.println("Date parsed = " + dateFormat.format(theDate));
	            Timestamp timeStampFinal=new Timestamp(theDate.getTime());
	            return timeStampFinal;
	        }catch (ParseException e) {
	            e.printStackTrace();
	        }
	       return t; ////////
		
	}//end setDateTime
	/**
	 * checks if hour in valid 
	 * @return boolean
	 */
	public boolean hourCheck(){
		try {
		int hour=Integer.parseInt(txtHh.getText());
		if (hour>23||hour<0)
			return false;
		}catch(NumberFormatException nFE){
			return false;
		}

			return true;
	}// end hourcheak
	/**
	 * checks if minute in valid 
	 * @return boolean
	 */
	public boolean minuteCheck(){
		try{
		int minute=Integer.parseInt(txtMm.getText());
		if (minute>59||minute<0)
			return false;
		}catch(NumberFormatException nFE){
		return false;
		}
			return true;
	}// end minutecheck
	
	public boolean checkCodeInput(String code)
	{
		if (code!=null)
		{int codeLength = code.length();
		
		if (codeLength != 4)
		{
			//code is not 4 characters
		
			return false;
		}
		int i;
		// check each character code 
		for (i = 0; i<4; i++ )
		{
			char ch =  code.charAt(i);
			if (ch<'0' || ch>'9' )
				if (ch<'A' || ch>'Z')
					if (ch<'a' || ch>'z'){
				JOptionPane.showMessageDialog(null,"on of the characters is not a number or letter");
				return false;
					}
			
				
		}
		executeTest.setTestCode(code);
		return true;}
		return false;
		
	}
	/**
	 * display the test chosen by teacher 
	 * @param selectedRow
	 */
	public void ViewExamSelect(int selectedRow)
	{
		Test testSelected =tdList.get(selectedRow);
		MessageQuestionListByTestID MsgGql = new MessageQuestionListByTestID(testSelected.getTestID());
		try {
			MS.client.sendToServer(MsgGql);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		ArrayList<QuestionInTest> qitList = (ArrayList<QuestionInTest>)MS.client.GetMessage();
		GUI_Test_View testFrame = new GUI_Test_View(qitList);
		testFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		testFrame.setResizable(false);
		testFrame.setVisible( true ); // display frame
	}
	
	/**
	 * this method gets an ArrayList<Question> and fills a table with all question in the subject
	 * @param confirmationAL
	 */
	public void populateTable(ArrayList<Test> exList) {

		String columnNames[] = {"ID","Subject","Author","Duration","Comment for Student","Comment for Teacher"};
		String tableModel[][] = new String[exList.size()][Teacher.NUM_OF_COLUMNS];
		for (int i=0; i<exList.size(); i++){
			tableModel[i][0] = exList.get(i).getTestID();
			tableModel[i][1] = exList.get(i).getSubject().getSubjectName();
			tableModel[i][2] = (exList.get(i).getAuthor().getUserFirstName() + " " + exList.get(i).getAuthor().getUserLastName());
			tableModel[i][3] = "" + exList.get(i).getTestDuration();
			tableModel[i][4] = exList.get(i).getCommentForStudent();
			tableModel[i][5] = exList.get(i).getCommentForTeacher();
			}// end for
		
		examJTable = new JTable(tableModel, columnNames){
			   public boolean isCellEditable(int rowIndex, int colIndex) {
			   return false; //Disallow the editing of any cell
			   }
			   };
			   scrollPane= new JScrollPane(examJTable);
		examJTable.setFont(new Font("Tahoma", Font.PLAIN, 14));
		examJTable.getTableHeader().setReorderingAllowed(false);
		//examJTable.setRowSelectionInterval(0, 0);
		TableColumn columnCorrect=examJTable.getColumnModel().getColumn(4);
		columnCorrect.setPreferredWidth(WIDTH*150);
		TableColumn columnCorrec=examJTable.getColumnModel().getColumn(5);
		columnCorrec.setPreferredWidth(WIDTH*150);
		examJTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		examJTable.getTableHeader().setReorderingAllowed(false);
		
		examJTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		panelTest.add(scrollPane);
		examJTable.setName("Test");
		panelTest.setVisible(true);
		this.validate();
		 this.repaint();
		}//end populated
	
	
/**
 * no test to display
 */

	private void noTstForTeacher() {
			panelTest.removeAll();
			JLabel noPendingRequests = new JLabel("No Exams In Subject");
			panelTest.add(noPendingRequests, BorderLayout.NORTH);
			panelTest.revalidate();
			panelTest.repaint();
			
		}
		

	/**
	 * This function display teacher Course list tought this semster in combo box 
	 * @param ArrayList<Course> - is array list of the teacher courses
	 */
	public void AvlialbleCoursesComboBox(ArrayList<Course> tCourses) {
		cmbCourses.removeAllItems();  //clear fields 
		if(tCourses.size() > 0){   
			cmbCourses.setEnabled(true);
			cmbCourses.addItem("Choose...");
			for (int i=0; i<tCourses.size(); i++){
				cmbCourses.addItem(tCourses.get(i).getCourseName());  //display the teacher Subject in combo box
			
			}
	    }// end if
	    else{
	    	cmbCourses.addItem("Not Available");
	    	cmbCourses.setEnabled(false);
	    }// end else
	}// end function AvlialbleCoursesComboBox
	
	public void showManualTest()
	{
		String str;
		str=findTestPath(tdList.get((examJTable.getSelectedRow())).getTestID());
		ExecuteTest exT =new ExecuteTest();
		exT.setWordTestPath(str);
		try
		{
			MessageGetWordFile msggwf = new MessageGetWordFile(exT);
			MS.client.sendToServer(msggwf);
			MyFile myFile = (MyFile)MS.client.GetMessage();
			File file = FileHandler.saveFileDialog("Save Test");
		   	String path = file.getAbsolutePath();
		    GetFileFromServer gffs = new GetFileFromServer(path);
			gffs.getFileFromServer(myFile);
			showMessage("Download Compelete", "Download Manual Test",JOptionPane.INFORMATION_MESSAGE );
		    			
		} 
		catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
	}
	
	public void getExamtoDisplay(){
		
		ArrayList<ExecuteTest> exList=new ArrayList<ExecuteTest>();
		tdList=new ArrayList<Test>();
		getExambyCourseID(courseChoosen);
		exList=getExecutedTest();
		if (tList.isEmpty()==true){
			noTstForTeacher();	//no test to display
			return;
		}
		
		if (exList.isEmpty()==true){	// no execute test to compare
			tdList=tList;
			populateTable(tdList);
			return;
		}
		for (int i=tList.size()-1;i>=0;i--){
				for(int j=0;j<exList.size();j++){
					if (exList.get(j).getTest().getTestID().equals(tList.get(i).getTestID()));
					if (exList.get(j).getTestSemster()==DateUtils.currentSemester()&&exList.get(j).getTestYear()!=DateUtils.currentYear())
						tList.remove(i);
						
					}
		}
		tdList=tList;
		populateTable(tdList);
	}
	/**
	 * This function returns exams by courseID
	 * @param courseID
	 */
	public void getExambyCourseID(String courseID){
		
		tList= new ArrayList<Test>();
		MessageExamOfCourse mTt = new MessageExamOfCourse(courseID,subjectId);
		try{
			MS.client.sendToServer(mTt);// get list of teacher subject
			
			tList = (ArrayList<Test>)MS.client.GetMessage();
			
			
	} catch (IOException e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	}

}// end getCourses
	
	/**
	 * This function returns the executed test 
	 * @param year 
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<ExecuteTest> getExecutedTest(){
		
		ArrayList<ExecuteTest> exList=new ArrayList<ExecuteTest>();
		MessageExcuteExamByCourseID mTs = new MessageExcuteExamByCourseID(courseChoosen,subjectId);
		try{
			MS.client.sendToServer(mTs);// get list of teacher subject
			
			 exList = (ArrayList<ExecuteTest>)MS.client.GetMessage();	 		
			
	} catch (IOException e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	}
		return exList;
		
	}// end getCourses
	/**
	 * This function returns the teacher tough  courses this tear this semester
	 * @param year 
	 */
	@SuppressWarnings("unchecked")
	public void getTeacherCourses(int year){
		int semester=DateUtils. currentSemester();
		MessageCoursesOfTeacher mTs = new MessageCoursesOfTeacher(user,year,semester);
		try{
			MS.client.sendToServer(mTs);// get list of teacher subject
			
			 cList = (ArrayList<Course>)MS.client.GetMessage();
		
			 AvlialbleCoursesComboBox(cList); 
			
			
	} catch (IOException e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	}}// end getCourses
	
	public JTextField getTxtHh() {
		return txtHh;
	}

	public JTextField getTxtMm() {
		return txtMm;
	}

	public void setTxtHh(JTextField txtHh) {
		this.txtHh = txtHh;
	}

	public void setTxtMm(JTextField txtMm) {
		this.txtMm = txtMm;
	}

	/**
	 * This function displays all the message from the System to the client GUI
	 * @param message The message to display
	 * @param title the title of the message
	 * @param messageType JOptionPane Enum as the message icon / type.
	 */
	public void showMessage(String message, String title, int messageType){
		JOptionPane.showMessageDialog(this,message,title,messageType);
	}// showMessage
}//GUI_Teacher_Execute_Exam
